﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data;
using System.Text;
using Sinacor.Infra.Service.Data;
using PSE.ProcessManager.Server.Process.Security;
using Sinacor.Infra.Core.ProcessManager.Server.Security;
using Sinacor.Infra.Service.Common;

namespace Sinacor.Process.Bovespa.MovimentoClube.Server.ResourceAccess
{
    public class Exportacao : BaseResourceAccess
    {
        #region Contrutor

        public Exportacao()
            : base(AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId)
        {
        }

        #endregion

        #region Metodos Publicos

        #region ObterCodigoEmpresaBolsa
        public int ObterCodigoEmpresaBolsa()
        {
            int retorno;

            string sqlCommand = @"SELECT TO_NUMBER(CD_EMPR_BOLSA)
                                  FROM TGELOCAL
                                  WHERE CD_EMPRESA = :CompanyId
                                        AND CD_BOLSA = 1 ";

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand))
            {
                this.DataBase.AddInParameter(command, "CompanyId", DbType.Int32, AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId);

                retorno = Convert.ToInt32(this.DataBase.ExecuteScalar(command));
            }

            return retorno;
        }
        #endregion

        #region ConsultarMovimentoClubeHeader
        public List<ProcessEntity.MovimentoClube> ConsultarMovimentoClubeHeader()
        {
            List<ProcessEntity.MovimentoClube> retorno = null;

            string sqlCommand = @"SELECT 
                                      ( '00' || 
                                      DECODE(TO_CHAR(TRUNC(SYSDATE),'yyyymmdd'), TO_CHAR(PARAM.DT_DATMOV,'yyyymmdd'), 'CLBD', 'CLBA') || 
                                      LPAD(TO_CHAR(LOCA.CD_EMPR_BOLSA),4,'0') ||
                                      'CLBC    ' ||
                                      LPAD(TO_CHAR(LOCA.CD_EMPR_BOLSA),4,'0') ||
                                      TO_CHAR(PARAM.DT_DATMOV,'yyyymmdd') ||
                                      TO_CHAR(PARAM.DT_DATMOV,'yyyymmdd') ) MovimentoClube
                                  FROM 
                                      TGELOCAL LOCA, 
                                      TGEEMPR EMPR, 
                                      TBOPARAM PARAM
                                  WHERE 
                                      LOCA.CD_BOLSA = '1'
                                      AND LOCA.CD_EMPRESA = :CodigoEmpresa1
                                      AND EMPR.CD_EMPRESA = LOCA.CD_EMPRESA
                                  GROUP BY 
                                      LOCA.CD_EMPR_BOLSA,
                                      EMPR.NM_EMPRESA,
                                      PARAM.DT_DATMOV, 
                                      LOCA.CD_CGC

                                  UNION ALL

                                  SELECT 
                                      ( '97' ||
                                      TO_CHAR(PARAM.DT_DATMOV,'dd/mm/yyyy') ||
                                      LPAD(LOCA.CD_CGC,14,'0') ||
                                      '60777661000150' ||
                                      'REM' ||
                                      '00001' ) MovimentoClube
                                  FROM
                                      TGELOCAL LOCA, 
                                      TGEEMPR EMPR, 
                                      TBOPARAM PARAM    
                                  WHERE
                                      LOCA.CD_BOLSA = '1'
                                      AND LOCA.CD_EMPRESA = :CodigoEmpresa2
                                      AND EMPR.CD_EMPRESA = LOCA.CD_EMPRESA
                                  GROUP BY 
                                      LOCA.CD_EMPR_BOLSA,
                                      EMPR.NM_EMPRESA,
                                      PARAM.DT_DATMOV, 
                                      LOCA.CD_CGC";

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand))
            {
                this.DataBase.AddInParameter(command, "CodigoEmpresa1", DbType.Int32, AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId);
                this.DataBase.AddInParameter(command, "CodigoEmpresa2", DbType.Int32, AuthenticationContext<SinacorAuthenticationData>.Current.AuthenticationData.CompanyId);

                retorno = this.FindAll<ProcessEntity.MovimentoClube>(command,
                      reader =>
                      {
                          ProcessEntity.MovimentoClube item = new ProcessEntity.MovimentoClube();

                          item.MovimentoClubeInvest = reader.GetValue<string>("MovimentoClube");

                          return item;
                      });
            }

            return retorno;
        }
        #endregion

        #region ConsultarMovimentoClubeTrailer
        #endregion

        #region ConsultarMovimentoClube
        public List<ProcessEntity.MovimentoClube> ConsultarMovimentoClube(ProcessEntity.Parameter.FiltroExportacaoMovimentoClube entity)
        {
            List<ProcessEntity.MovimentoClube> retorno = null;

            StringBuilder sqlCommand = new StringBuilder(
                                @"SELECT 
                                    -- COLUNA 01
                                    ('04' ||
                                    RPAD(TO_CHAR(DETF.DT_NEGOCIO, 'dd/mm/yyyy'),25,' ') ||
                                    RPAD(TO_CHAR(DETF.CD_CLIENTE), 32, ' ') ||    
                                    -- COLUNA 02    
                                    RPAD(DECODE(NEGD.TP_MERCADO, 'FRA', SUBSTR(DETF.CD_NEGOCIO, 1, LENGTH(DETF.CD_NEGOCIO) -1), DETF.CD_NEGOCIO), 20, ' ') ||
                                    -- COLUNA 03 
                                    NEGD.CD_CODISI || 
                                    RPAD(DETF.CD_NATOPE, 9, ' ') ||    
                                    -- COD EMPRESA BOLSA
                                    RPAD(:CodigoEmpresaBolsa1, 28, ' ') ||     
                                    RPAD(:CodigoEmpresaBolsa2, 20, ' ') ||    
                                    -- COLUNA 04
                                    DECODE(DETF.CD_BOLSAMOV, '1', 'SP', '5', 'SO', '8', 'MS', 'SP') ||
                                    SUBSTR(TO_CHAR((DETF.QT_QTDESP + 1000000000000 ) * 1000000000000), 2, 24) ||
                                    SUBSTR(TO_CHAR((NEGD.VL_NEGOCIO + 1000000000000) * 1000000000000), 2, 24) ||
                                    RPAD('S' || 'N', 10, ' ') || 
                                    -- COD EMPRESA BOLSA
                                    RPAD(:CodigoEmpresaBolsa3, 20, ' ') ||     
                                    -- COLUNA 05
                                    TO_CHAR(DECODE(NEGD.ID_LIQUID, 0, CALB.DT_MOV, 1, CALB.PZ_LIQ_FUT, CALB.PZ_PROJ_CC ), 'DD/MM/YYYY') || 
                                    SUBSTR((1000 + TRUNC(ABS(DETF.PC_REDACR), 6 )) * 1000000, 2, 9) || 
                                    SUBSTR(TO_CHAR((DETF.VL_TOTNEG + 1000000000000) * 1000000000000), 2, 24) || 
                                    SUBSTR(TO_CHAR((DETF.VL_CORTOT + 1000000000000) * 1000000000000 ), 2, 24) || 
                                    SUBSTR(TO_CHAR((1000000000000 + DECODE(SIGN(DETF.VL_CORTOT - DETF.VL_CORRET), -1, 0, DETF.VL_CORTOT - DETF.VL_CORRET)) * 1000000000000), 2, 24) || 
                                    SUBSTR(TO_CHAR((1000000000000 + DETF.VL_TXREG + DETF.VL_EMOLUM + DETF.VL_VALDES) * 1000000000000), 2, 24) ||
                                    -- COLUNA 06
                                    SUBSTR(TO_CHAR((1000000000000 + ABS(DECODE(DETF.CD_NATOPE, 'C', -DETF.VL_TOTNEG, DETF.VL_TOTNEG) - DETF.VL_CORRET - DETF.VL_TXREG - DETF.VL_EMOLUM - DETF.VL_VALDES)) * 1000000000000), 2, 24) ||
                                    -- COLUNA 07    
                                    'RV1') MovimentoClube      
                                FROM 
                                    TORNEGD NEGD, 
                                    TBODETFIN01 DETF, 
                                    TSCCLISIS CLIS, 
                                    TBOCALBOL CALB    
                                WHERE 
                                    DETF.DT_DATMOV = :DataMovimento
                                    AND DETF.DT_NEGOCIO = :DataNegocio
                                    AND DETF.CD_BOLSAMOV = NEGD.CD_BOLSAMOV
                                    AND DETF.NR_NEGOCIO = NEGD.NR_NEGOCIO
                                    AND DETF.CD_NATOPE = NEGD.CD_NATOPE
                                    AND DETF.DT_NEGOCIO = NEGD.DT_PREGAO
                                    AND DETF.CD_NEGOCIO = NEGD.CD_NEGOCIO
                                    AND DETF.CD_CLIENTE = CLIS.CD_CLIENTE
                                    AND CLIS.IND_EXPT_BANC_BMF = 'S'
                                    AND CALB.CD_PRACA = DETF.CD_BOLSAMOV
                                    AND CALB.DT_MOV = DETF.DT_NEGOCIO
                                    AND DETF.CD_BOLSAMOV = '1'
                                    AND NEGD.TP_MERCADO NOT IN ('VFU', 'CET')
                                    AND SUBSTR(NEGD.CD_CODISI, 7, 2) <> 'PP'");
                        
            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand.ToString()))
            {
                this.DataBase.AddInParameter(command, "CodigoEmpresaBolsa1", DbType.Int32, entity.CodigoEmpresaBolsa.Value);
                this.DataBase.AddInParameter(command, "CodigoEmpresaBolsa2", DbType.Int32, entity.CodigoEmpresaBolsa.Value);
                this.DataBase.AddInParameter(command, "CodigoEmpresaBolsa3", DbType.Int32, entity.CodigoEmpresaBolsa.Value);
                this.DataBase.AddInParameter(command, "DataMovimento", DbType.DateTime, entity.DataPregao.Value);
                this.DataBase.AddInParameter(command, "DataNegocio", DbType.DateTime, entity.DataPregao.Value);
                
                if (entity.Prazo == Sinacor.Process.Bovespa.MovimentoClube.ProcessEntity.Enum.Prazo.D0)
                {
                    sqlCommand.AppendLine(" AND (NEGD.TP_MERCADO IN ('VIS','FRA') OR DETF.IN_LIQUIDA = 'A')");
                }

                if (entity.Prazo == Sinacor.Process.Bovespa.MovimentoClube.ProcessEntity.Enum.Prazo.D1)
                {
                    sqlCommand.AppendLine(" AND NEGD.TP_MERCADO IN ('VIS','FRA')");
                }

                command.CommandText = sqlCommand.ToString();

                retorno = this.FindAll<ProcessEntity.MovimentoClube>(command,
                      reader =>
                      {
                          ProcessEntity.MovimentoClube item = new ProcessEntity.MovimentoClube();

                          item.MovimentoClubeInvest = reader.GetValue<string>("MovimentoClube");

                          return item;
                      });
            }

            return retorno;
        }
        #endregion               

        #region RealizarMontagemFAX
        public ProcessEntity.Resultado RealizarMontagemFAX(ProcessEntity.Parameter.FiltroMontagemFAX entity)
        {
            ProcessEntity.Resultado retorno = null;
            StringBuilder sqlCommand = new StringBuilder();

            sqlCommand.Append(" DECLARE rettype BOOLEAN; ");
            sqlCommand.Append(" BEGIN ");
            sqlCommand.Append(" rettype:= PBO_FAX.fBO_FAX (:CodigoCliente, :DataAtual, :DataMovimento, 'C', :DataMontagemFAX, :MaquinaUsuario, :TipoChamada, :R_nErro, :R_sErro, :R_sArgs); ");
            sqlCommand.Append(" IF rettype THEN :R_Retorno := 1; ELSE :R_Retorno := 0; END IF; ");
            sqlCommand.Append(" END; ");

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand.ToString()))
            {
                // Input Parameters
                this.DataBase.AddInParameter(command, "CodigoCliente", DbType.Int32, entity.CodigoCliente);
                this.DataBase.AddInParameter(command, "DataAtual", DbType.String, entity.DataPregao.ToString("dd-MM-yyyy"));
                this.DataBase.AddInParameter(command, "DataMovimento", DbType.String, entity.DataPregao.ToString("dd-MM-yyyy"));
                this.DataBase.AddInParameter(command, "DataMontagemFAX", DbType.String, entity.DataMontagemFAX);
                this.DataBase.AddInParameter(command, "MaquinaUsuario", DbType.String, (entity.MaquinaUsuario.Length > 15)? entity.MaquinaUsuario.Substring(0, 15) : entity.MaquinaUsuario);
                this.DataBase.AddInParameter(command, "TipoChamada", DbType.String, String.Empty);
                // Output Parameters
                this.DataBase.AddOutParameter(command, "R_nErro", DbType.Int32, 4);
                this.DataBase.AddOutParameter(command, "R_sErro", DbType.String, 1000);
                this.DataBase.AddOutParameter(command, "R_sArgs", DbType.String, 2000);
                this.DataBase.AddOutParameter(command, "R_Retorno", DbType.Int32, 4);

                this.DataBase.ExecuteNonQuery(command);

                retorno = new ProcessEntity.Resultado();

                if (Convert.ToBoolean(this.DataBase.GetParameterValue(command, "R_Retorno")))
                {
                    retorno.Sucesso = true;
                }
                else
                {
                    retorno.Sucesso = false;
                    retorno.CodigoErro = Convert.ToInt32(this.DataBase.GetParameterValue(command, "R_nErro"));
                    retorno.Argumentos = Convert.ToString(this.DataBase.GetParameterValue(command, "R_sArgs"));
                }
            }

            return retorno;
        }
        #endregion

        #region ConsultarClientesPorClube
        public List<ProcessEntity.Parameter.FiltroMontagemFAX> ConsultarClientesPorClube(ProcessEntity.Parameter.FiltroExportacaoMovimentoClube entity)
        {
            List<ProcessEntity.Parameter.FiltroMontagemFAX> retorno = null;

            string sqlCommand = @"SELECT 
                                     DISTINCT COMI.CD_CLIENTE CodigoCliente
                                  FROM 
                                     TORCOMI COMI,
                                     TSCCLISIS CLISIS             
                                  WHERE 
                                     CLISIS.CD_CLIENTE = COMI.CD_CLIENTE
                                     AND COMI.DT_NEGOCIO = :DataPregao
                                     AND CLISIS.IND_EXPT_BANC_BMF = 'S'";

            using (DbCommand command = this.DataBase.GetSqlStringCommand(sqlCommand))
            {
                this.DataBase.AddInParameter(command, "DataPregao", DbType.Date, entity.DataPregao.Value);

                retorno = this.FindAll<ProcessEntity.Parameter.FiltroMontagemFAX>(command,
                                      reader =>
                                      {
                                          ProcessEntity.Parameter.FiltroMontagemFAX item = new ProcessEntity.Parameter.FiltroMontagemFAX();
                                            
                                          item.CodigoCliente = reader.GetValue<Int32>("CodigoCliente");
                                                                     
                                          return item;
                                      });
            }

            return retorno;
        }
        #endregion

        #endregion
    }
}
